/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author jefoutta
 */
import java.io.*;
import java.util.*;

public class PCB {
    public static Hashtable<Integer,PCB> proc_id = new Hashtable();
    public static LinkedList<Integer> procList = new LinkedList();
    private static Integer proc_id_i = 0;
    public Integer id;
    public Integer priority;
    public Integer queue = 1;
    public Integer job = null;
    public Integer ticks = 0;
    public Integer totalTicks = 0;
    public Integer lastTick = 0;
    public Integer startTick = 0;
    public Integer waitingTime = 0;
    public Integer totalWaitingTime = 0;
    public Integer readyWaitingTime = 0;
    public Integer arriveTick = null;
    public Integer leaveTick;
    public Integer createTick;
    public Integer responseTime = 0;
    public Integer turnaraundTime = 0;
    private Integer state;
    public boolean quantum = false;
    public boolean IO = false;
    public boolean syn = false;
    private StringTokenizer tokenizer;
    public String fname;
    public String pname;
    private ArrayList<Integer> procChildrenId = new ArrayList(0);
    public static String listatemp1 = "";
    public static String listatemp2 = "";
    private StringTokenizer priorityparameter;

    public PCB(String s) throws IOException{
        priorityparameter = new StringTokenizer(s, " ");
        String ptemp;
        while(priorityparameter.hasMoreTokens()){
            ptemp = priorityparameter.nextToken();
            if(ptemp.contains("p"))
                priority = Integer.parseInt(ptemp.split("p")[1]);
            else
                priority = 4;
        }
        this.fname = null;
        this.pname = s;
        queue = 1;
        id = proc_id_i;
        if(s.contains(">")){
            syn = true;
            tokenizer = new StringTokenizer(s,">");
            tokenizer.nextToken();
            fname = tokenizer.nextToken();
        }
        
        this.state = 2;
        listatemp1 = listatemp1 + this.id;
        proc_id.put(id, this);
        procList.addLast(id);
        createTick = Scheduling.totalTicks;
        Scheduling.inputProc(this.id);
        //Scheduling.proc_queue.addLast(this.id);
        
        proc_id_i++;
    }

    public  PCB(Integer idt, String s){
        priorityparameter = new StringTokenizer(s, " ");
        String ptemp;
        while(priorityparameter.hasMoreTokens()){
            ptemp = priorityparameter.nextToken();
            if(ptemp.contains("p"))
                priority = Integer.parseInt(ptemp.split("p")[1]);
            else
                priority = 4;
        }
        this.fname = null;
        this.pname = s;
        this.state = 2;
        queue = 1;
        this.id = proc_id_i;
        listatemp2 = listatemp2 + this.id;
        proc_id.put(proc_id_i, this);
        procList.addLast(proc_id_i);
        createTick = Scheduling.totalTicks;
        proc_id.get(idt).setState(4);
        Scheduling.inputProc(this.id);
        //Scheduling.proc_queue.addLast(this.id);
        
        proc_id.get(idt).procChildrenId.add(proc_id_i);
        proc_id_i++;
    }

    public void setState(Integer n){
        this.state = n;
    }

    public Integer getState(){
        return this.state;
    }

    public String getProcessName(){
        return this.pname;
    }

    public String getFileName(){
        return this.fname;
    }

    public boolean getSyn(){
        return this.syn;
    }

    public boolean tick(Integer tquantum){
        ticks++;
        if (((ticks - lastTick) % tquantum) == 0)
            return true;
        else
            return false;
    }

    public void takeTick(Integer schtick){
        //ticks = ticks + schtick - waitingTime - startTick;
        startTick = schtick;
        if (arriveTick == null){
            arriveTick = startTick;
            responseTime = startTick - createTick;
        }
        //if (lastTick > 0)
            //waitingTime = waitingTime + schtick - lastTick - 5;
    }

    public void leaveTick(Integer schtick){
        lastTick = schtick;
        ticks = ticks + schtick - startTick;
        totalTicks = totalTicks + schtick - startTick;
        leaveTick = schtick;
        readyWaitingTime = leaveTick - arriveTick - totalTicks;
        turnaraundTime = totalWaitingTime + totalTicks + readyWaitingTime;

        if(IO){

            ticks = 0;
        }

        if(ProcQueue.procQueues.get(queue).preemptive == 1){
            Scheduling.preemptive = true;
            //state = 4;
            //ticks = 0;
        }

        if (ticks == ProcQueue.procQueues.get(queue).quantum){
            quantum = true;
            Scheduling.quantum = true;
            state = 4;
            ticks = 0;
        }
    }

    public void waiting(){
        waitingTime++;
        totalWaitingTime++;
    }

    public static String Stats(){
        return null;
    }

    public String toString(){
        String temp = this.pname + ":";
        temp = temp + "\n Turnaraund Time: " + turnaraundTime;
        temp = temp + "\n Waiting Time: "+ readyWaitingTime;
        temp = temp + "\n Response Time: " + responseTime;
        temp = temp + "\n Excecuting Time: " + totalTicks + "\n";
        return temp;
    }
}